import React, { useState, useEffect, useRef } from 'react';
import { Stage, Layer, Image, Transformer } from 'react-konva';
import { Icon, Slider } from 'antd';
import imagePromise from 'image-promise';
import classNames from 'classnames';
import Konva from 'konva';
import update from 'immutability-helper';
import title from '@/assets/title.png';
import basicForeground from '@/assets/logos/basic.png';
import goldForeground from '@/assets/logos/gold.png';
import whiteForeground from '@/assets/logos/white.png';
import blueForeground from '@/assets/logos/blue.png';
// import testBackground from '@/assets/testImage2.png';
import styles from './index.less';

const appWidth = Math.min(window.innerWidth, window.innerHeight, 600);
const FILTERS = [
  { icon: 'deployment-unit', name: 'hue', text: '色相', defaultValue: 0, min: 0, max: 359, step: 1 },
  { icon: 'experiment', name: 'saturation', text: '饱和度', defaultValue: 0, min: -5, max: 5, step: 0.1 },
  { icon: 'bulb', name: 'luminance', text: '明度', defaultValue: 0, min: -1, max: 1, step: 0.1 },
]

const DEFAULT_FILTER_VALUES = FILTERS.map(item => item.defaultValue)
const DEFAULT_LAYER = 1;
const FILTERS_LENGTH = FILTERS.length;
const DEFAULT_FILTER_INDEX = 0;
const FILTER_NAMES = FILTERS.map(item => item.name);

const FOREGROUNDS = {
  basic: basicForeground,
  gold: goldForeground,
  white: whiteForeground,
  blue: blueForeground,
}


export default function () {
  const [background, SET_background] = useState(null); // 背景图
  const [foreground, SET_foreground] = useState(null); // 前景图
  const [resultImage, SET_resultImage] = useState(null); // 生成的合成图
  const [colorControlsVisible, SET_colorControlsVisible] = useState(false); // 调色控制台开关
  const [filterLayer, SET_filterLayer] = useState(DEFAULT_LAYER); // 滤镜对哪个图层生效
  const [filterIndex, SET_filterIndex] = useState(DEFAULT_FILTER_INDEX); // 当前滤镜Index
  const [filterValues, SET_filterValues] = useState([...DEFAULT_FILTER_VALUES, ...DEFAULT_FILTER_VALUES]); // 滤镜值数组
  const [currentForegroundKey, SET_currentForegroundKey] = useState('basic'); // 前景图片key
  const stageRef = useRef(null);
  const backgroundRef = useRef(null);
  const foregroundRef = useRef(null);
  const transformerRef = useRef(null);

  const stageWidth = background ? Math.min(background.width, appWidth) : 0;
  const stageHeight = background ? background.height * stageWidth / background.width : 0;
  const foregroundMaxWidth = background && foreground ? Math.min(stageWidth, foreground.width) : 0;
  const foregroundDefaultWidth = background && foreground ? foregroundMaxWidth * 0.8 : 0;
  const foregroundDefaultHeight = background && foreground ? foreground.height * foregroundDefaultWidth / foreground.width : 0;
  const foregroundDefaultX = (stageWidth - foregroundDefaultWidth) / 2;
  const foregroundDefaultY = (stageHeight - foregroundDefaultHeight) / 2;

  const currentFilterValueIndex = filterLayer * FILTERS_LENGTH + filterIndex;

  const loadImage = async (newImageURL, layerIndex) => {
    const newImage = await imagePromise(newImageURL);
    if (layerIndex) {
      SET_foreground(newImage);
    } else {
      SET_background(newImage);
    }
  }

  useEffect(() => {
    loadImage(FOREGROUNDS[currentForegroundKey], 1); // 加载前景图
  }, [currentForegroundKey]);

  // 显示定界框
  const showTransformer = () => {
    transformerRef.current.detach();
    transformerRef.current.attachTo(foregroundRef.current);
    transformerRef.current.getLayer().batchDraw();
  }

  // 隐藏定界框
  const hideTransformer = () => {
    transformerRef.current.detach();
    transformerRef.current.getLayer().batchDraw();
  }

  // 如果前景或背景变化,
  useEffect(() => {
    showTransformer();
    foregroundRef.current.cache();
    foregroundRef.current.filters([Konva.Filters.HSL]);
    foregroundRef.current.getLayer().batchDraw();
  }, [foreground])

  useEffect(() => {
    backgroundRef.current.cache();
    backgroundRef.current.filters([Konva.Filters.HSL]);
    backgroundRef.current.getLayer().batchDraw();
  }, [background])

  // 滤镜值改变，刷新画面
  useEffect(() => {
    const refreshByValues = (targetRef, layerIndex) => {
      targetRef.current.cache();
      FILTER_NAMES.forEach((item, index) => {
        targetRef.current[item](filterValues[layerIndex * FILTERS_LENGTH + index])
        return true;
      })
      targetRef.current.getLayer().batchDraw();
    }
    foregroundRef && refreshByValues(foregroundRef, 1);
    backgroundRef && refreshByValues(backgroundRef, 0);
  }, [filterValues])


  // 上传背景图片
  const uploadBackground = () => {
    const backgroundInput = document.createElement('input');
    backgroundInput.setAttribute('type', 'file');
    backgroundInput.setAttribute('accept', 'image/*');
    backgroundInput.setAttribute('style', 'display: none');
    backgroundInput.addEventListener('change', async (e) => {
      if (e.target.files != null) {
        const file = e.target.files[0];
        const fileReader = new FileReader();
        fileReader.onloadend = () => {
          imagePromise(fileReader.result).then(SET_background);
        }
        fileReader.readAsDataURL(file)
        document.querySelector('body').removeChild(backgroundInput);
      }
    });
    document.querySelector('body').appendChild(backgroundInput);
    backgroundInput.click();
  }


  // 从生成结果图片状态返回编辑状态
  const backEditor = () => {
    SET_resultImage(null);
    showTransformer();
  }

  // 生成结果图片
  const exportToResultImage = () => {
    hideTransformer();
    const pixelRatio = Math.max(1, background.width / appWidth);
    const resultImage = stageRef.current.toDataURL({ mimeType: 'image/png', pixelRatio });
    SET_resultImage(resultImage);
  }

  // 点击舞台，根据点击位置显示或隐藏前景图定界框
  const onStageClick = (e) => {
    if (e.target.hasName('foreground')) {
      showTransformer();
    } else {
      hideTransformer();
    }
  }

  // 显示调色器
  const showColorControls = () => {
    SET_colorControlsVisible(true);
  }

  // 隐藏调色器
  const hideColorControls = () => {
    SET_colorControlsVisible(false);
  }
  // 切换调色器
  const onFilterClick = (index) => {
    SET_filterIndex(index);
  }

  const onFilterControlChange = (value) => {
    const newValues = update(filterValues, {
      [currentFilterValueIndex]: { $set: value }
    })
    SET_filterValues(newValues)
  }

  const toggleTargetLayer = () => {
    SET_filterLayer(Number(!filterLayer));
  }

  return (
    <div className={styles.app}>
      <div className={classNames({ [styles.hide]: background })}>
        <div className={styles.title}>
          <img src={title} alt='' width={375} />
        </div>
        <div className={styles.uploader} onClick={uploadBackground}></div>
      </div>

      <div className={classNames(styles.body, { [styles.hide]: resultImage || !background })}>
        <div className={styles.content}>
          <Stage
            width={stageWidth}
            height={stageHeight}
            ref={stageRef}
            onTap={onStageClick}
            onClick={onStageClick}
          >
            <Layer>
              <Image ref={backgroundRef} name="background" image={background} width={stageWidth} height={stageHeight} />
            </Layer>
            <Layer draggable>
              <Image ref={foregroundRef} name="foreground" image={foreground} width={foregroundDefaultWidth} height={foregroundDefaultHeight} x={foregroundDefaultX} y={foregroundDefaultY} />
              <Transformer
                ref={transformerRef}
                keepRatio={true}
              />
            </Layer>
          </Stage>
        </div>
        <div className={styles.foot}>
          <div className={classNames(styles.foregroundSelect, { [styles.hide]: colorControlsVisible })}>
            {Object.keys(FOREGROUNDS).map(key => (<img
              key={key}
              className={classNames(styles.thumb, { [styles.active]: key === currentForegroundKey })}
              src={FOREGROUNDS[key]}
              alt={key}
              onClick={() => SET_currentForegroundKey(key)}
            />))}
          </div>
          <div className={classNames(styles.buttonGroup, { [styles.hide]: colorControlsVisible })}>
            <div className={styles.button} onClick={uploadBackground}>
              <Icon type="upload" />
              <span>上传</span>
            </div>
            <div className={styles.button} onClick={showColorControls}>
              <Icon type="control" />
              <span>调色</span>
            </div>
            <div className={styles.button} onClick={exportToResultImage}>
              <Icon type="export" />
              <span>生成</span>
            </div>
          </div>
          <div className={classNames(styles.controls, { [styles.hide]: !colorControlsVisible })}>
            <div className={styles.control}>
              <Icon type={FILTERS[filterIndex].icon} />
              <Slider
                className={styles.slider}
                value={filterValues[currentFilterValueIndex]}
                onChange={onFilterControlChange}
                tipFormatter={null}
                min={FILTERS[filterIndex].min}
                max={FILTERS[filterIndex].max}
                step={FILTERS[filterIndex].step}
              />
            </div>
            <div className={styles.filtersWrap}>
              <div className={styles.close} onClick={hideColorControls}>
                <Icon type="arrow-left" />
              </div>
              <div
                className={classNames(styles.targetLayer, [styles[`layer${filterLayer}`]])}
                onClick={toggleTargetLayer}
              >
                <div className={styles.icon}>
                  <div className={styles.bottom}></div>
                  <div className={styles.top}></div>
                </div>
                <span>{filterLayer ? '前景' : '背景'}</span>

              </div>
              <div className={styles.filters}>
                {FILTERS.map((item, index) => (<div
                  className={classNames(styles.filter, { [styles.active]: filterIndex === index })}
                  key={item.name}
                  onClick={() => onFilterClick(index)}
                >
                  <Icon type={item.icon} />
                  <span>{item.text}</span>
                </div>))}
              </div>

            </div>

          </div>


        </div>
      </div>

      <div className={classNames(styles.body, { [styles.hide]: !resultImage })}>
        <div className={styles.content}>
          <img src={resultImage} alt='' width="100%" />
        </div>
        <div className={styles.foot}>
          <div className={styles.resultFoot}>
            <div className={styles.help}>请右键存储图片或长按保存</div>
            <div className={styles.backEditorButton} onClick={backEditor}>
              <div>返回编辑器</div>
              <div className={styles.subText}>BACK EDITOR</div>
            </div>
          </div>

        </div>
      </div>

    </div>
  );
}
